package com.compiler.model;

import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;

import java.util.ArrayList;
import java.util.List;

import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;

/**
 * Created by huilin on 2017/6/10.
 */

public class AnnotatedClass {
    /**
     * 类名
     */
    private TypeElement typeElement;
    private List<BindViewField> bindViewFields;
    private List<OnClickMethod> onClickMethods;
    /**
     *
     */
    private Elements elements;

    public AnnotatedClass(TypeElement typeElement, Elements elements) {
        this.typeElement = typeElement;
        this.elements = elements;
        bindViewFields = new ArrayList<>();
        onClickMethods = new ArrayList<>();
    }

    /**
     * 获取当前类的全名
     *
     * @return
     */
    public String getFullClassName() {
        return typeElement.getQualifiedName().toString();
    }

    public void addField(BindViewField bindViewField) {
        bindViewFields.add(bindViewField);
    }

    public void addMethod(OnClickMethod onClickMethod) {
        onClickMethods.add(onClickMethod);
    }

    public JavaFile generateFile() {
        //构建方法
        MethodSpec.Builder injectMethodBuilder = MethodSpec.methodBuilder("inject")
                .addAnnotation(Override.class)//添加注解
                .addModifiers(Modifier.PUBLIC)//添加描述
                .addParameter(TypeName.get(typeElement.asType()), "host", Modifier.FINAL)
                .addParameter(TypeName.OBJECT, "object")
                .addParameter(ClassName.get("xtu.www.inject.provide", "Provider"), "provide");
        for (BindViewField bindViewField : bindViewFields) {
            //
            injectMethodBuilder.addStatement("host.$N=($T)provide.findView(object,$L)",
                    bindViewField.getFieldName(), ClassName.get(bindViewField.getFieldTypes()), bindViewField.getrId());
        }
        if(!onClickMethods.isEmpty()){
            injectMethodBuilder.addStatement("$T  listener",ClassName.get("android.view","View","OnClickListener"));
        }

        for (OnClickMethod onClickMethod : onClickMethods){
            TypeSpec listener = TypeSpec.anonymousClassBuilder("")
                    .addSuperinterface(ClassName.get("android.view","View","OnClickListener"))
                    .addMethod(MethodSpec.methodBuilder("onClick")
                            .addParameter(ClassName.get("android.view","View"),"view")
                            .addAnnotation(Override.class)
                            .returns(TypeName.VOID)
                            .addModifiers(Modifier.PUBLIC)
                            .addStatement("host.$N()",onClickMethod.getMethodName()).build()
                    ).build();
            injectMethodBuilder.addStatement("listener = $L",listener);
            for (int id :onClickMethod.getRIds()){
                injectMethodBuilder.addStatement("provide.findView(object,$L).setOnClickListener(listener)",id);
            }
        }
        //生成class
        TypeSpec injectClass = TypeSpec.classBuilder(typeElement.getSimpleName() + "$$ViewInject")
                .addModifiers(Modifier.PUBLIC)
                .addSuperinterface(ParameterizedTypeName.get(ClassName.get("xtu.www.inject", "Inject"), TypeName.get(typeElement.asType())))//
                .addMethod(injectMethodBuilder.build())
                .build();
        return JavaFile.builder(getPackageName(), injectClass).build();

    }

    public String getPackageName() {
        return elements.getPackageOf(typeElement).getQualifiedName().toString();
    }
}
